package aima.test.core.unit.environment.vacuum;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import aima.core.environment.vacuum.ReflexVacuumAgent;
import aima.core.environment.vacuum.VacuumEnvironment;

/**
 * @author Ciaran O'Reilly
 * 
 */
public class ReflexVacuumAgentTest {
	private ReflexVacuumAgent agent;

	private StringBuilder envChanges;

	@Before
	public void setUp() {
		agent = new ReflexVacuumAgent();
		envChanges = new StringBuilder();
	}

	@Test
	public void testDirtyDirtyDirtyDirty() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Suck]Action[name==Down]Action[name==Suck]Action[name==Left]Action[name==Suck]Action[name==Up]",
				envChanges.toString());
	}

	@Test
	public void testDirtyDirtyDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Suck]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]",
				envChanges.toString());
	}

	@Test
	public void testDirtyDirtyCleanDirty() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Suck]Action[name==Down]Action[name==Suck]Action[name==Left]Action[name==Up]Action[name==Right]",
				envChanges.toString());
	}
	
    @Test
	public void testDirtyDirtyCleanClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Suck]Action[name==Down]Action[name==Left]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
	
    @Test
	public void testDirtyCleanDirtyDirty() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Dirty);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Suck]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]",
				envChanges.toString());
	}
	
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanCleanDirty() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Suck]Action[name==Left]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanCleanClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Up]Action[name==Right]Action[name==Down]Action[name==Left]",
				envChanges.toString());
	}

    //-------------
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
    
    @Test
	public void testDirtyCleanDirtyClean() {
		VacuumEnvironment tve = new VacuumEnvironment(
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean,
				VacuumEnvironment.LocationState.Dirty,
				VacuumEnvironment.LocationState.Clean);
		tve.addAgent(agent, VacuumEnvironment.LOCATION_A);

		tve.addEnvironmentView(new EnvironmentViewActionTracker(envChanges));

		tve.step(8);

		Assert.assertEquals(
				"Action[name==Suck]Action[name==Right]Action[name==Down]Action[name==Left]Action[name==Suck]Action[name==Up]Action[name==Right]Action[name==Down]",
				envChanges.toString());
	}
}
